package com.yang.job.infra.gatewayimpl.repository.convertor;

import com.yang.job.domain.enums.JobExecuteStrategyEnum;
import com.yang.job.domain.model.YangJobModel;
import com.yang.job.infra.data.YangJobData;
import com.yang.job.infra.job.execute.IYangJobExecutor;
import com.yang.job.infra.job.execute.YangJobExecuteRequest;
import com.yang.job.infra.utils.FeaturesUtils;
import org.springframework.stereotype.Component;

@Component
public class YangJobModelConvertor {
    public YangJobData convert2Data(YangJobModel yangJobModel) {
        if (yangJobModel == null) {
            return null;
        }
        YangJobData yangJobData = new YangJobData();
        yangJobData.setJobId(yangJobModel.getJobId());
        yangJobData.setJobName(yangJobModel.getJobName());
        yangJobData.setDescription(yangJobModel.getDescription());
        yangJobData.setCron(yangJobModel.getCron());
        yangJobData.setExecuteClassPath(yangJobModel.getExecuteClassPath());
        yangJobData.setEnable(yangJobModel.getEnable());
        yangJobData.setOpen(yangJobModel.getOpen());
        yangJobData.setCreateTime(yangJobModel.getCreateTime());
        yangJobData.setUpdateTime(yangJobModel.getUpdateTime());
        yangJobData.setFeatures(FeaturesUtils.convert2Features(yangJobModel.getFeatureMap()));
        yangJobData.setExecuteParams(FeaturesUtils.convert2Features(yangJobModel.getExecuteParamMap()));
        yangJobData.setExecuteStrategy(yangJobModel.getExecuteStrategy().getName());
        return yangJobData;
    }

    public YangJobModel convert2Model(YangJobData yangJobData) {
        if (yangJobData == null) {
            return null;
        }
        YangJobModel yangJobModel = new YangJobModel();
        yangJobModel.setJobId(yangJobData.getJobId());
        yangJobModel.setDescription(yangJobData.getDescription());
        yangJobModel.setCron(yangJobData.getCron());
        yangJobModel.setJobName(yangJobData.getJobName());
        yangJobModel.setExecuteClassPath(yangJobData.getExecuteClassPath());
        yangJobModel.setEnable(yangJobData.getEnable());
        yangJobModel.setOpen(yangJobData.getOpen());
        yangJobModel.setCreateTime(yangJobData.getCreateTime());
        yangJobModel.setUpdateTime(yangJobData.getUpdateTime());
        yangJobModel.setFeatureMap(FeaturesUtils.convert2FeatureMap(yangJobData.getFeatures()));
        yangJobModel.setExecuteParamMap(FeaturesUtils.convert2FeatureMap(yangJobData.getExecuteParams()));
        JobExecuteStrategyEnum executeStrategy = JobExecuteStrategyEnum.getJobExecuteStrategyByName(yangJobData.getExecuteStrategy());
        if (executeStrategy == null) {
            throw new RuntimeException("执行策略有误!");
        }
        yangJobModel.setExecuteStrategy(executeStrategy);
        String executeClassPath = yangJobData.getExecuteClassPath();
        try {
            Class<?> aClass = Class.forName(executeClassPath);
            if (!IYangJobExecutor.class.isAssignableFrom(aClass)) {
                throw new RuntimeException("该类必须实现IYangJobExecutor接口");
            }
            IYangJobExecutor executor = (IYangJobExecutor) aClass.newInstance();
            YangJobExecuteRequest yangJobExecuteRequest = convert2YangJobExecuteRequest(yangJobData);
            Runnable runnable = () -> executor.execute(yangJobExecuteRequest);
            yangJobModel.setRunnable(runnable);
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            System.out.println(String.format("%s 类路径对应的类不存在", executeClassPath));
            e.printStackTrace();
        }
        return yangJobModel;
    }

    private static YangJobExecuteRequest convert2YangJobExecuteRequest(YangJobData yangJobData) {
        YangJobExecuteRequest yangJobExecuteRequest = new YangJobExecuteRequest();
        yangJobExecuteRequest.setJobId(yangJobData.getJobId().toString());
        yangJobExecuteRequest.setParams(FeaturesUtils.convert2FeatureMap(yangJobData.getExecuteParams()));
        return yangJobExecuteRequest;
    }
}
